import * as THREE from 'three'
import { Main } from './main'

export class Rubik {
    private BASIC_PARAMS = {
        x: 0,
        y: 0,
        z: 0,
        num: 3,
        len: 40,
        //右、左、上、下、前、后
        colors: ['#ff6b02', '#dd422f',
            '#ffffff', '#fdcd02',
            '#3d81f7', '#019d53']
    }
    public group!: THREE.Group
    private main!: Main
    public cube!: THREE.Mesh[]
    public container!: THREE.Mesh

    public xLine!: THREE.Vector3
    public yLine!: THREE.Vector3
    public zLine!: THREE.Vector3
    public xLineAd!: THREE.Vector3
    public yLineAd!: THREE.Vector3
    public zLineAd!: THREE.Vector3


    constructor(main: Main) {
        this.main = main

        //魔方的六个转动方向
        this.xLine = new THREE.Vector3(1, 0, 0);
        this.xLineAd = new THREE.Vector3(-1, 0, 0);
        this.yLine = new THREE.Vector3(0, 1, 0);
        this.yLineAd = new THREE.Vector3(0, -1, 0);
        this.zLine = new THREE.Vector3(0, 0, 1);
        this.zLineAd = new THREE.Vector3(0, 0, -1);
    }

    private faces(rgbaColor: string) {
        const canvas = document.createElement('canvas');
        canvas.width = 256;
        canvas.height = 256;
        const context = canvas.getContext('2d');
        //画一个宽高都是256的黑色正方形
        context!.fillStyle = 'rgba(0,0,0,1)';
        context!.fillRect(0, 0, 256, 256);
        //在内部用某颜色的16px宽的线再画一个宽高为224的圆角正方形并用改颜色填充
        context!.rect(16, 16, 224, 224);
        context!.lineJoin = 'round';
        context!.lineWidth = 16;
        context!.fillStyle = rgbaColor;
        context!.strokeStyle = rgbaColor;
        context!.stroke();
        context!.fill();
        return canvas;
    }


    private SimpleCube(x: number, y: number, z: number, num: number, len: number) {
        //魔方左上角坐标
        const leftUpX = x - num / 2 * len;
        const leftUpY = y + num / 2 * len;
        const leftUpZ = z + num / 2 * len;

        const cubes = [];
        for (let i = 0; i < num; i++) {
            for (let j = 0; j < num * num; j++) {

                const myFaces = [];
                for (let k = 0; k < 6; k++) {
                    myFaces[k] = this.faces(this.BASIC_PARAMS.colors[k]);
                }

                const materials = [];
                for (let k = 0; k < 6; k++) {
                    const texture = new THREE.Texture(myFaces[k]);
                    texture.needsUpdate = true;
                    materials.push(new THREE.MeshLambertMaterial({ map: texture }));
                }

                const cubegeo = new THREE.BoxGeometry(len, len, len);
                const cube = new THREE.Mesh(cubegeo, materials);

                //依次计算各个小方块中心点坐标
                cube.position.x = leftUpX + (j % num) * len;
                cube.position.y = leftUpY - Math.floor(j / num) * len;
                cube.position.z = leftUpZ - i * len;
                cube.name = `box${i}${j}`
                cubes.push(cube)
            }
        }

        return cubes
    }

    public model(name: string) {

        this.group = new THREE.Group()
        this.group.name = name

        this.cube = this.SimpleCube(this.BASIC_PARAMS.x, this.BASIC_PARAMS.y, this.BASIC_PARAMS.z, this.BASIC_PARAMS.num, this.BASIC_PARAMS.len)

        this.group.add(...this.cube)

        if (name === this.main.frontViewName) {
            this.group.rotateY(45 / 180 * Math.PI);
        } else if (name === this.main.backViewName) {
            this.group.rotateY((270 - 45) / 180 * Math.PI);
        }

        this.group.rotateOnAxis(new THREE.Vector3(1, 0, 1), 25 / 180 * Math.PI);

        this.main.scene.add(this.group)

        const width = this.BASIC_PARAMS.num * this.BASIC_PARAMS.len + 20
        const cubegeo = new THREE.BoxGeometry(width, width, width);
        const cubemat = new THREE.MeshBasicMaterial({ color: 0xffffff, opacity: 0, transparent: true });
        this.container = new THREE.Mesh(cubegeo, cubemat);
        this.container.position.y = 20
        this.container.position.z = 20
        this.container.position.x = -20
        this.container.name = 'coverCube'
        this.group.add(this.container)
    }

    resizeHeight(percent: number, transformTag: number) {
        if (percent < this.main.minPercent) {
            percent = this.main.minPercent;
        }
        if (percent > (1 - this.main.minPercent)) {
            percent = 1 - this.main.minPercent;
        }
        this.group.scale.set(percent, percent, percent);
        this.group.position.y = this.main.originHeight * (0.5 - percent / 2) * transformTag;
    }

    // 计算转动方向
    private getDirection() {

    }

}